package com.pro.common.modules.service.dependencies.config.component;

import cn.hutool.core.util.ByteUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pro.common.api.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

@ControllerAdvice
public class ApiResponseWrapper implements ResponseBodyAdvice<Object> {

    @Autowired
    private ObjectMapper objectMapper;
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        Class<?> returnClass = returnType.getParameterType();
        if (org.springframework.core.io.Resource.class.isAssignableFrom(returnClass)) {
            return false;
        }

        // 不包装 ResponseEntity<Resource> （因为ResponseEntity泛型擦除，判断返回类型是 ResponseEntity 也跳过）
        if (ResponseEntity.class.isAssignableFrom(returnClass)) {
            // 你也可以额外判断泛型，但泛型擦除后只能用其它标记手段
            // 简单做法：如果返回的是 ResponseEntity 且 Content-Type 是流类型，跳过包装
            return false;
        }
        return true; // 拦截所有返回类型
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  ServerHttpRequest request, ServerHttpResponse response) {
        // 如果是 Feign 调用，不做包装
        if (isFeignRequest(request)) return body;
        // 过滤 Swagger / Knife4j 相关接口
        String path = request.getURI().getPath();
        if (isSwaggerRequest(path)) {
            return body;
        }
        // 如果已经是 ApiResponse 类型，直接返回
        if (body instanceof R<?> || body instanceof byte[]) {
            return body;
        }
//        if (body instanceof R<?> || body instanceof ResponseEntity<?>) {
//            return body;
//        }
        // 如果原始返回体是 String 类型，则需要将包装后的对象转换为 JSON 字符串返回
        if (body instanceof String) {
            try {
//                ObjectMapper mapper = new ObjectMapper();
                // 设置 Content-Type 为 application/json
                response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
                return objectMapper.writeValueAsString(R.ok(body));
            } catch (JsonProcessingException e) {
                throw new RuntimeException("转换 JSON 失败", e);
            }
        }
        return R.ok(body);
    }

    // 判断是否是 Feign 请求
    private boolean isFeignRequest(ServerHttpRequest request) {
        return "true".equals(request.getHeaders().getFirst("X-Feign-Request"));
    }

    // 判断是否是 Swagger / Knife4j 相关请求
    private boolean isSwaggerRequest(String path) {
        return path.startsWith("/swagger") ||
                path.startsWith("/v3/api-docs") ||
                path.startsWith("/v2/api-docs") ||
                path.startsWith("/webjars") ||
                path.startsWith("/doc.html") ||  // Knife4j 文档地址
                path.startsWith("/swagger-resources");
    }
}
